package com.lin.filegraph.utils.componentRule;

import com.lin.filegraph.utils.threshold.Threshold;
import com.lin.filegraph.utils.compdg.ComponentEdge;
import com.lin.filegraph.utils.compdg.ComponentGraph;
import com.lin.filegraph.utils.compdg.ComponentNode;

/**
 * @description:
 * @author: linhuaixu
 * @time: 2023/5/18 15:53
 */

public class DetectCouples {

    public static void removeCouples(ComponentGraph graph) {
        ComponentEdge cpe = findMaxCouple(graph);
        if (cpe != null) {
            ComponentNode cn1 = cpe.getPreComponent();
            ComponentNode cn2 = cpe.getPostComponent();
            if(cn2.isFeature()!=true&&cn2.isFeature()!=true) {
                graph.mergeNodes(cn2, cn1);
                removeCouples(graph);
            }
        }
    }

    /**
     * 无规模限制
     */
    public static void removeFullCouples(ComponentGraph graph) {
        ComponentEdge cpe = findMaxCouple2(graph);
        if (cpe != null) {
            ComponentNode cn1 = cpe.getPreComponent();
            ComponentNode cn2 = cpe.getPostComponent();
            graph.mergeNodes(cn2, cn1);
            removeFullCouples(graph);
        }
    }

    private static ComponentEdge findMaxCouple(ComponentGraph graph) {
        double depend = 0, tempDepend = 0;
        ComponentEdge cpe = null;
        for (ComponentEdge ce : graph.getAllComponentEdges()) {
            ComponentNode cn1 = ce.getPreComponent();
            ComponentNode cn2 = ce.getPostComponent();
            if(cn1.isFeature()==true||cn2.isFeature()==true)
                continue;
            if (isSize(cn1, cn2, graph.getTotalSize())){
                double dep = ce.getDependence() / (cn1.getAllFiles().size() * cn2.getAllFiles().size());
                if (dep > depend || (dep == depend && tempDepend > ce.getDependence())) {
                    if (graph.getPostComponents(cn2).contains(cn1)) {
                        depend = dep;
                        cpe = ce;
                        tempDepend = ce.getDependence();
                    }
                }
            }
        }
        return cpe;
    }


    private static ComponentEdge findMaxCouple2(ComponentGraph graph) {
        double depend = 0, tempDepend = 0;
        ComponentEdge cpe = null;
        for (ComponentEdge ce : graph.getAllComponentEdges()) {
            ComponentNode cn1 = ce.getPreComponent();
            ComponentNode cn2 = ce.getPostComponent();
            if ((cn1.getAllFiles().size() +cn2.getAllFiles().size()) <graph.getTotalSize()* Threshold.comScale2){
                double dep = ce.getDependence() / (cn1.getAllFiles().size() * cn2.getAllFiles().size());
                if (dep > depend || (dep == depend && tempDepend > ce.getDependence())) {
                    if (graph.getPostComponents(cn2).contains(cn1)) {
                        depend = dep;
                        cpe = ce;
                        tempDepend = ce.getDependence();
                    }
                }
            }
        }
        return cpe;
    }

    /**
     * 控制单个组件规模
     */
    public static boolean isSize(ComponentNode pre, ComponentNode post, int comSize) {
//		if (pre.getAllFiles().size() > comSize * Threshold.comScale2 &&post.getAllFiles().size() > comSize * Threshold.comScale2)
        if((pre.getAllFiles().size() +post.getAllFiles().size()) < comSize * Threshold.COMSCALE)
            return true;
        if (pre.getAllFiles().size() < Threshold.MINMINCOM)
            return true;
        if (post.getAllFiles().size() < Threshold.MINMINCOM)
            return true;
        return false;
    }

}
